void main() {
  var list = List<int>();
  list.add(1);
  const list1 = [1, 2];
  for (var l in list1) {
    print(l);
  }

  var map = Map<String, int>();
  var map1 = const {"foo": 2, "bar": 3};
  var map2 = <String, int>{};

  dynamic obj = <String, int>() {};
  if (obj is Map<String, int>) {
    obj["t"] = 1;
  }
  print("----------------------");
  print(foo(1, 2));
  print(foo(1));
  print("----------------------");
  var adder = makeAdder(2);
  print(adder(1, 2));
  print("----------------------");

  var point = OffsetPoint(1, 2, 10);
  // 使用 getter/setter 时，就像它是一个普通的成员变量
  print(point.x);
  print(point);
  point.x = 4;
  print(point);
  print("----------------------");
  var pair = Pair("hello", 1);
  print(pair is Pair<String, int>);
  print(pair is! Pair<int, int>);
  print(pair is Pair);
  print("----------------------");
  var naturals = naturalsTo(10);
  naturals.forEach((f) => print(f));
  print("----------------------");
  var asynchronousNaturals = asynchronousNaturalsTo(10);
  asynchronousNaturals.forEach((f) => print(f));
}

int foo(int x, [int y]) {
  // 是的，int 也可以是 null
  if (y != null) {
    return x + y;
  }
  return x;
}

typedef Adder = Function(int, int);

Adder makeAdder(int extra) {
//  int adder(int x, int y) {
//    return x + y + extra;
//  }
//  return adder;
  return (int x, int y) => x + y + extra;
}

Function makeAdder1(int extra) {
  int adder(int x, int y) {
    return x + y + extra;
  }

  return adder;
}

class Point2D {
  int x;
  int y;

//  Point2D(int x, int y){
//    this.x=x;
//    this.y=y;
//  }
//  Point2D(this.x, this.y);
  // 由于是在 initializer list 中，Dart 知道第一个 x 是 this.x，
  // 第二个 x 是构造函数的参数
  Point2D(int x, int y)
      : x = x,
        y = y {}
}

class Point3D extends Point2D {
  int z;

  Point3D(int x, int y, this.z) : super(x, y);
}

class OffsetPoint {
  int _x;
  int _y;
  int offset;

  OffsetPoint(this._x, this._y, this.offset);

  int get x => _x + offset;

  int get y => _y + offset;

  set x(int value) => _x = value;

  set y(int value) => _y = value;

  @override
  String toString() {
    return "OffsetPoint{x=$x, y=$y}";
  }
}

class Pair<S, T> {
  S first;
  T second;

  Pair(this.first, this.second);
}

//同步生成器：返回Iterable对象
Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}

//异步生成器：返回Stream对象
Stream<int> asynchronousNaturalsTo(int n) async* {
  int k = 0;
  while (k < n) yield k++;
}
